#ifndef __WEBCLIENT_H__
#define __WEBCLIENT_H__

#include <stdio.h>

#include "ofc/ofc_types.h"
//#include "webclient_utils.h"
#include "web_client/http_client_interface.h"

#if defined(WEBCLIENT_USING_MBED_TLS) || defined(WEBCLIENT_USING_SAL_TLS)
#include <tls_client.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define WEBCLIENT_SW_VERSION           "2.2.0"
#define WEBCLIENT_SW_VERSION_NUM       0x20200

#define WEBCLIENT_HEADER_BUFSZ         4096
#define WEBCLIENT_RESPONSE_BUFSZ       4096

#define WEBCLIENT_HOST_LEN      (64)
#define WEBCLIENT_URL_LEN       (200)

enum WEBCLIENT_STATUS
{
    WEBCLIENT_OK,
    WEBCLIENT_ERROR,
    WEBCLIENT_TIMEOUT,
    WEBCLIENT_NOMEM,
    WEBCLIENT_NOSOCKET,
    WEBCLIENT_NOBUFFER,
    WEBCLIENT_CONNECT_FAILED,
    WEBCLIENT_DISCONNECT,
    WEBCLIENT_FILE_NOT_EXISTS_ERROR,
    WEBCLIENT_PATH_ERROR,
    WEBCLIENT_HTTPS_ERROR,
};

enum WEBCLIENT_METHOD
{
    WEBCLIENT_USER_METHOD,
    WEBCLIENT_GET,
    WEBCLIENT_POST,
};

struct  webclient_header
{
    char *buffer;
    size_t length;                      /* content header buffer size */

    size_t size;                        /* maximum support header size */
};

struct webclient_session
{
    struct webclient_header header;    /* webclient response header information */
    IHttpClientSocket       *socket;   ///< socket对象

    char  host[WEBCLIENT_HOST_LEN];     /* server host */
    char  req_url[WEBCLIENT_URL_LEN];   /* HTTP request address*/
    Int32 port;                         /* server host */                     

    int chunk_sz;
    int chunk_offset;

    int resp_status;                   ///< 应答状态
    int content_length;        ///< 本次文本长度
    int content_offset;        ///< 文本偏移量
    int content_total_size;    ///< 文本总长度
    int content_remainder;           /* remainder of content length */

    Bool is_tls;                   /* HTTPS connect */
#ifdef WEBCLIENT_USING_MBED_TLS
    MbedTLSSession *tls_session;        /* mbedtls connect session */
#endif
};

/* create webclient session and set header response size */
void webclient_session_create(struct webclient_session *self, IHttpClientSocket *socket, char *head_buf, Int32 head_len);

/* send HTTP GET request */
int webclient_get(struct webclient_session *session, const char *URI);
int webclient_get_position(struct webclient_session *session, const char *URI, int position);
int webclient_get_range(struct webclient_session *self, const char *URI, int offset, int size);

/* send HTTP POST request */
int webclient_post(struct webclient_session *self, const char *URI, const void *post_data, size_t data_len);

/* close and release wenclient session */
int webclient_close(struct webclient_session *self, Bool is_close);

// int webclient_set_timeout(struct webclient_session *session, int millisecond);

/* send or receive data from server */
int webclient_read(struct webclient_session *session, void *buffer, size_t size);
int webclient_write(struct webclient_session *session, const void *buffer, size_t size);

#if 1
int webclient_header_fields_add(struct webclient_session *session, const char *fmt, ...);
#else
#define webclient_header_fields_add(SESSION, FORMAT, ...) ({ \
    int length = snprintf((char*)SESSION->header.buffer + SESSION->header.length, SESSION->header.size - SESSION->header.length, FORMAT, ##__VA_ARGS__); \
    SESSION->header.length += length;\
    length = SESSION->header.length >= SESSION->header.size ? -1 : length; \
    length; \
})
#endif

const char *webclient_header_fields_get(struct webclient_session *session, const char *fields);

/* send HTTP POST/GET request, and get response data */
// int webclient_response(struct webclient_session *session, void **response, size_t *resp_len);
// int webclient_request(const char *URI, const char *header, const void *post_data, size_t data_len, void **response, size_t *resp_len);
// int webclient_request_header_add(char **request_header, const char *fmt, ...);
int webclient_resp_status_get(struct webclient_session *session);
int webclient_content_length_get(struct webclient_session *session);
int webclient_content_offset_get(struct webclient_session *self);
int webclient_content_total_size_get(struct webclient_session *self);
int webclient_handle_response(struct webclient_session *self);
#ifdef RT_USING_DFS
/* file related operations */
int webclient_get_file(const char *URI, const char *filename);
int webclient_post_file(const char *URI, const char *filename, const char *form_data);
#endif

#ifdef  __cplusplus
    }
#endif

#endif
